// A Program to extract lines that contain a sub string.
// By DreamVB 02:07 07/10/2016

#include <iostream>
#include <fstream>
#include <string>

using namespace std;
using std::cout;
using std::endl;

string LCase(const string& src)
{
	string dest(src);

	for (char& ch : dest)
		ch = tolower(ch);

	return dest;
}

bool IsInString(string source, string substr, bool AnyCaae = false){

	bool Found = false;
	int pos = string::npos;
	int FlagOr = string::npos;
	int FlagAnd = string::npos;

	int chk1 = string::npos;
	int chk2 = string::npos;

	string sTemp0 = source;
	string sTemp1 = substr;

	if (AnyCaae){
		sTemp0 = LCase(sTemp0);
		sTemp1 = LCase(sTemp1);
	}

	//Check if sub string is in s0
	pos = sTemp0.find(sTemp1);

	FlagOr = sTemp1.find("|");
	FlagAnd = sTemp1.find("&");

	if (FlagOr != string::npos){
		chk1 = sTemp0.find(sTemp1.substr(0, FlagOr));
		chk2 = sTemp0.find(sTemp1.substr(FlagOr + 1));

		if ((chk1 != string::npos) || (chk2!=string::npos)){
			Found = true;
		}
	}
	else if (FlagAnd != string::npos){
		chk1 = sTemp0.find(sTemp1.substr(0, FlagAnd));
		chk2 = sTemp0.find(sTemp1.substr(FlagAnd + 1));

		if ((chk1 != string::npos) && (chk2 != string::npos)){
			Found = true;
		}
	}
	else{
		if (pos != string::npos){
			Found = true;
		}
	}

	return Found;
}

int main(int argc, char *argv[]){
	ifstream fs;
	int i = 3;
	bool MatchAnyCase = false;

	string StrLine = "";
	string Flag = "";

	if (argc < 2){
		cout << "Usage: " << argv[0] << " <source> [patten]" << endl;
		cout << "See /? for more information." << endl;
		exit(1);
	}
	
	//Get flag
	Flag = argv[1];

	//Check for help
	if (argc == 2){
		//Check flag
		if (Flag == "/?"){
			cout << argv[0] << " <filename> [patten] [/O]" << endl << endl;
			cout << "  source         The input filename to scan." << endl;
			cout << "  patten         The string patten to find." << endl;
			cout << "  /O             Ignore patten case." << endl;
			return 0;
		}
		return 0;
	}

	//Check for other flags
	while (i < argc){
		Flag = LCase(argv[i]);
		if (Flag == "/o"){
			MatchAnyCase = true;
		}
		i++;
	}

	//Open input file.
	fs.open(argv[1], ios::in || ios::binary);

	//See if file was opened.
	if (!fs.good()){
		cout << "Error reading input filename." << endl;
		exit(1);
	}

	cout << "Please wait extracting data..." << endl;

	while (getline(fs,StrLine)){
		if (IsInString(StrLine, argv[2], MatchAnyCase)){
			//Output line found
			cout << StrLine.c_str() << endl;
		}
	}

	//Close file.
	fs.close();
	return 0;
}